﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;

namespace Sofire.Data.XSql
{
    #region 基类

    /// <summary>
    /// 表示一个可编译的 XSql 节点。
    /// </summary>
    public interface IXSqlCompile
    {
        /// <summary>
        /// 编译 XSql 语句。
        /// </summary>
        /// <param name="parameters">参数集合。</param>
        /// <returns>返回一个字符串。</returns>
        string Compile(XSqlParameterCollection parameters);
    }

    /// <summary>
    /// 表示 XSql 的集合。
    /// </summary>
    public interface IXSqlCollection : IXSqlCompile, IEnumerable<IXSql> { }

    /// <summary>
    /// 表示 <see cref="Sofire.Data.XSql.IXSqlNode"/> 的集合。
    /// </summary>
    public interface IXSqlNodeCollection : IEnumerable<IXSqlNode> { }

    /// <summary>
    /// 表示一个 XSql。
    /// </summary>
    public interface IXSql : IXSqlCompile
    {
        /// <summary>
        /// 获取当前 XSql 的父节点。
        /// </summary>
        IXSql Parent { get; }
        /// <summary>
        /// 获取当前 XSql 的下一个节点。
        /// </summary>
        IXSql Next { get; }
        /// <summary>
        /// 获取当前 XSql 的上一个节点。
        /// </summary>
        IXSql Previous { get; }
        /// <summary>
        /// 获取当前 XSql 的子节点集合。
        /// </summary>
        IXSqlCollection Children { get; }
        /// <summary>
        /// 获取当前 XSql 的文档。
        /// </summary>
        IXSqlDocument Document { get; }
        /// <summary>
        /// 获取当前 XSql 的类型。
        /// </summary>
        XSqlType Type { get; }
        /// <summary>
        /// 获取当前 XSql 的原始 XML 内容。
        /// </summary>
        string Xml { get; }
        /// <summary>
        /// 加载 XSql 数据。
        /// </summary>
        /// <param name="node">一个 <see cref="System.Xml.XmlNode"/>。</param>
        void Load(XmlNode node);
    }

    /// <summary>
    /// 表示一个具有名称的节点。
    /// </summary>
    public interface INameNode
    {
        /// <summary>
        /// 获取名称。
        /// </summary>
        string Name { get; }
    }

    /// <summary>
    /// 表示一个具有名称的 <see cref="Sofire.Data.XSql.IXSql"/> 节点。
    /// </summary>
    public interface IXSqlName : IXSql, INameNode
    {
    }

    /// <summary>
    /// 表示一个具有测试的 <see cref="Sofire.Data.XSql.IXSql"/> 节点。
    /// </summary>
    public interface IXSqlTest : IXSql
    {
        /// <summary>
        /// 表示进行测试的表达式。
        /// </summary>
        string Test { get; }
        /// <summary>
        /// 表示进行测试的表达式前缀。
        /// </summary>
        string TestPrefix { get; }
    }

    /// <summary>
    /// 表示一个具有移除前导与后部结果的 <see cref="Sofire.Data.XSql.IXSql"/> 节点。
    /// </summary>
    public interface IXSqlTrim : IXSql
    {
        /// <summary>
        /// 从当前编译结果中，移除所有前导匹配项和尾部匹配项。用“|”分隔头尾的字符，如“,|.”。
        /// </summary>
        string Trim { get; }
    }

    #endregion

    /// <summary>
    /// 表示一个 XSql 集合文档。
    /// </summary>
    public interface IXSqlDocument : INameNode
    {
        /// <summary>
        /// 获取指定 XSql 名称的 <see cref="Sofire.Data.XSql.IXSqlNode"/> 对象。
        /// </summary>
        /// <param name="name">XSql 名称。</param>
        /// <returns>返回一个 <see cref="Sofire.Data.XSql.IXSqlNode"/> 对象，或一个 null 值。</returns>
        IXSqlNode this[string name] { get; }
        /// <summary>
        /// 获取数据库操作引擎。
        /// </summary>
        QueryEngineBase Engine { get; }
        /// <summary>
        /// 获取 XSql 集合。
        /// </summary>
        IXSqlNodeCollection XSqls { get; }
        /// <summary>
        /// 创建并返回当前文档的 XML 内容。
        /// </summary>
        /// <returns>返回当前文档的 XML 内容。</returns>
        string CreateXml();
        /// <summary>
        /// 保存当前文档。
        /// </summary>
        /// <param name="fileName">文档的路径。</param>
        void Save(string fileName);
        /// <summary>
        /// 保存当前文档。
        /// </summary>
        /// <param name="writer">文本写入器。</param>
        void Save(System.IO.TextWriter writer);
        /// <summary>
        /// 保存当前文档。
        /// </summary>
        /// <param name="writer">xml 写入器。</param>
        void Save(XmlWriter writer);
        /// <summary>
        /// 指定 XSql 名称，创建一个填充命令和参数的 <see cref="Sofire.Data.ExecuteCommand"/> 实例。
        /// </summary>
        /// <param name="name">XSql 名称。</param>
        /// <returns>返回一个填充命令和参数的 <see cref="Sofire.Data.ExecuteCommand"/> 实例。</returns>
        ExecuteCommand CreateCommand(string name);
        /// <summary>
        /// 指定 XSql 名称，创建一个填充命令和参数的 <see cref="Sofire.Data.ExecuteCommand"/> 实例。
        /// </summary>
        /// <param name="name">XSql 名称。</param>
        /// <param name="parameters">参数集合。</param>
        /// <returns>返回一个填充命令和参数的 <see cref="Sofire.Data.ExecuteCommand"/> 实例。</returns>
        ExecuteCommand CreateCommand(string name, XSqlParameterCollection parameters);
        /// <summary>
        /// 指定一个 <see cref="Sofire.Data.XSql.IXSqlNode"/>，创建一个填充命令和参数的 <see cref="Sofire.Data.ExecuteCommand"/> 实例。
        /// </summary>
        /// <param name="xsql">一个 <see cref="Sofire.Data.XSql.IXSqlNode"/>。</param>
        /// <returns>返回一个填充命令和参数的 <see cref="Sofire.Data.ExecuteCommand"/> 实例。</returns>
        ExecuteCommand CreateCommand(IXSqlNode xsql);
        /// <summary>
        /// 指定一个 <see cref="Sofire.Data.XSql.IXSqlNode"/>，创建一个填充命令和参数的 <see cref="Sofire.Data.ExecuteCommand"/> 实例。
        /// </summary>
        /// <param name="xsql">一个 <see cref="Sofire.Data.XSql.IXSqlNode"/>。</param>
        /// <param name="parameters">参数集合。</param>
        /// <returns>返回一个填充命令和参数的 <see cref="Sofire.Data.ExecuteCommand"/> 实例。</returns>
        ExecuteCommand CreateCommand(IXSqlNode xsql, XSqlParameterCollection parameters);
    }

    /// <summary>
    /// 表示一个 <see cref="Sofire.Data.XSql.XSqlType.XSql"/> 节点。
    /// </summary>
    public interface IXSqlNode : IXSqlName
    {
        /// <summary>
        /// 获取缓存的模式。
        /// </summary>
        XSqlCacheMode CacheMode { get; }
        /// <summary>
        /// 获取参数忽略列表。
        /// </summary>
        string Ignores { get; }
    }

    /// <summary>
    /// 表示一个 <see cref="Sofire.Data.XSql.XSqlType.Procedure"/> 节点。
    /// </summary>
    public interface IXSqlProcedureNode : IXSqlNode { }

    /// <summary>
    /// 表示一个 <see cref="Sofire.Data.XSql.XSqlType.Expression"/> 节点。
    /// </summary>
    public interface IXSqlExpressionNode : IXSqlName
    {
        /// <summary>
        /// 获取表达式内容。
        /// </summary>
        string Expression { get; }
        /// <summary>
        /// 编译表达式。
        /// </summary>
        /// <param name="parameters">参数集合。</param>
        /// <returns>返回一个值。</returns>
        object CompileObject(XSqlParameterCollection parameters);
    }

    #region 语法

    /// <summary>
    /// 表示一个 <see cref="Sofire.Data.XSql.XSqlType.If"/> 节点。
    /// </summary>
    public interface IXSqlIfNode : IXSqlTest { }

    /// <summary>
    /// 表示一个 <see cref="Sofire.Data.XSql.XSqlType.Else"/> 节点。
    /// </summary>
    public interface IXSqlElseNode : IXSql { }

    /// <summary>
    /// 表示一个 <see cref="Sofire.Data.XSql.XSqlType.Switch"/> 节点。
    /// </summary>
    public interface IXSqlSwitchNode : IXSqlTest { }

    /// <summary>
    /// 表示一个 <see cref="Sofire.Data.XSql.XSqlType.Case"/> 节点。
    /// </summary>
    public interface IXSqlCaseNode : IXSqlTest { }

    /// <summary>
    /// 表示一个 <see cref="Sofire.Data.XSql.XSqlType.Default"/> 节点。
    /// </summary>
    public interface IXSqlDefaultNode : IXSql { }

    /// <summary>
    /// 表示一个 <see cref="Sofire.Data.XSql.XSqlType.Foreach"/> 节点。
    /// </summary>
    public interface IXSqlForeachNode : IXSqlTrim
    {
        /// <summary>
        /// 获取循环的初始变量名。
        /// </summary>
        string Var { get; }
        /// <summary>
        /// 获取循环的集合参数名。
        /// </summary>
        string In { get; }
        /// <summary>
        /// 获取循环时的索引变量名。
        /// </summary>
        string Index { get; }
    }

    #endregion

    /// <summary>
    /// 表示一个 <see cref="Sofire.Data.XSql.XSqlType.Include"/> 节点。
    /// </summary>
    public interface IXSqlIncludeNode : IXSql
    {
        /// <summary>
        /// 获取引用的路径。可以是一个 <see cref="Sofire.Data.XSql.IXSqlNode"/> 的名称，或 *.xsql 文件的路径。
        /// </summary>
        string Path { get; }
        /// <summary>
        /// 获取引用路径的文档。默认为 null 值，表示当前文档。
        /// </summary>
        string Owner { get; }
    }

    /// <summary>
    /// 表示一个 <see cref="Sofire.Data.XSql.XSqlType.Trim"/> 节点。
    /// </summary>
    public interface IXSqlTrimNode : IXSqlTrim
    {
        /// <summary>
        /// 获取一个值，指示当子集合的内容不为空时添加的字首。
        /// </summary>
        string Prefix { get; }
    }

    /// <summary>
    /// 表示一个 <see cref="Sofire.Data.XSql.XSqlType.Parameters"/> 节点。
    /// </summary>
    public interface IXSqlParametersNode : IXSql { }

    /// <summary>
    /// 表示一个 <see cref="Sofire.Data.XSql.XSqlType.Parameter"/> 节点。
    /// </summary>
    public interface IXSqlParameterNode : INameNode
    {
        /// <summary>
        /// 获取参数的输入输出类型。
        /// </summary>
        System.Data.ParameterDirection Direction { get; }
        /// <summary>
        /// 获取一个值，指示参数的必要性。
        /// </summary>
        bool Required { get; }
        /// <summary>
        /// 获取一个值，表示参数的新命名。
        /// </summary>
        string To { get; }
    }
    /// <summary>
    /// 表示一个 <see cref="Sofire.Data.XSql.XSqlType.Text"/> 节点。
    /// </summary>
    public interface IXSqlTextNode : IXSql
    {
        /// <summary>
        /// 获取当前 XSql 的文本内容。
        /// </summary>
        string Text { get; }
    }

    ///// <summary>
    ///// 表示一个 <see cref="Sofire.Data.XSql.XSqlType.Test"/> 节点。
    ///// </summary>
    //public interface IXSqlTestNode : IXSqlTextNode { }
}
